package jupiter.servlets;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import jupiter.channel.Session;
import jupiter.filters.Filter;
import jupiter.filters.FilterException;
import jupiter.message.Message;
import jupiter.message.NotRegisteredException;
import jupiter.util.Application;
import jupiter.util.EventSubscriber;
import jupiter.util.Timey;

import org.json.JSONObject;
import org.mortbay.jetty.RetryRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RequestHandler {
	
	static Logger logger = LoggerFactory.getLogger(RequestHandler.class);
	static public void service(HttpServletRequest req, HttpServletResponse res, EventSubscriber subscriber) throws java.io.IOException {
		//System.out.println("req");
		try{
			String mes = get_data(req);
//			http://127.0.0.1:8080/message?data=test_error
			if(mes.indexOf("test_error") != -1)
				throw new Exception("Testing error handling");
			//check to make sure compound messages aren't being sent
			String multipart = get_multipart(req);
			if(multipart != null){
				System.out.println(" Multipart is true ");
				HttpSession session = req.getSession(false);
				if(session != null){
					String currentData = (String) session.getAttribute("multipartData");
					//check if there is already data, we should also check a maximum length (2 MB)
					if(currentData == null)
						currentData = mes;
					else
						currentData = currentData + mes;
					
					//check if you are done or not
					if(multipart.compareTo("complete") == 0){
						mes = currentData;
						session.removeAttribute("multipartData");
					}else{
						session.setAttribute("multipartData", currentData);
						sendResult(req, res, "null");
						System.out.println("Saved multipart fragment");
						Session sn = (Session) session.getAttribute("sessionChannel");
						if(sn != null) sn.resume();
						return;
					}
				}else{
					System.out.println("To long of a message without a session");
				}
			}
			Message message = new Message( mes, req, res );
			
			//logger.info("***Message: "+message.toString());
			JSONObject response = null;
			String result_string = null;
			String result = null;
			//if(message.type.compareTo("session") == 0 && message.action.compareTo("connect") == 0 ){
			//	System.out.println("doing it");
			//	response = new SessionFilter().connect(message);
			//}else{
				try{
					response = Filter.filter(message, false); 			//throw FilterException 
					//System.out.println("SENDING TEXT TO EVERYONE");
					String message_json = message.toString();
					if(subscriber != null)
						subscriber.sendText(message_json);    //if you don't want to send to all jabbify domains
//					System.out.println("\n---------------------------------------------\n"+message_json+"\n");
					result = getResult(response);
				}catch(RetryRequest e){
					throw e;
				}catch(FilterException e){
					if(e.json_string != null)
						result = getResult(e.json_string);
					else
						result = getResult(e.json);
					if(e.releaseContinuation()){ //This also happens in DN for messages that aren't sent
						HttpSession session = req.getSession(false);
						if(session != null){
							Session sn = (Session) session.getAttribute("sessionChannel");
							if(sn != null){
								sn.resume();
							}
						}
					}
				}catch(Throwable thr){
					logger.error("Caught Error ", thr);
				}
			//}
			
			
			 //  message.send();
			/*if(message.is_registered == false){
				this.register(message, req, res);
				return;
			}*/
			sendResult(req, res, result);
//			t.end("Message");
		}catch(RetryRequest e){
			throw e;
		}catch(RuntimeException e){
			logger.error("RuntimeException in MessageServlet", e);
			throw e;
	    }catch(Exception e){
	    	System.out.println(e);
			logger.error("Exception in MessageServlet: "+req.getQueryString()+", "+req.getRemoteHost(), e);
	    }
	}
	static public String getResult(JSONObject response){
		String res = response == null ? "null" : response.toString();
//		System.out.println("\n---------------------------------------------JSONObject: \n"+res+"\n");
		return res;
	}
	static public String getResult(String response){
		String res = response == null ? "null" : response;
//		System.out.println("\n---------------------------------------------string: \n"+res+"\n");
		return res;
	}
	static public String get_data(HttpServletRequest req){
		String query = req.getQueryString();
		// optimizing for the most common case
		if(query.indexOf("%22session%22") != -1 && query.indexOf("%22connect%22") != -1){
			return "{\"type\": \"session\", \"action\": \"connect\", \"data\": {}}";
		}
		return req.getParameter("data");
	}
	static public String get_multipart(HttpServletRequest req){
		return req.getParameter("multipart");
	}
	static public void sendResult(HttpServletRequest req, HttpServletResponse res, String result) throws java.io.IOException {
		String callback = req.getParameter("callback");
		//String nocallback = req.getParameter("nocallback");
		if(callback != null){
			res.setContentType("text/javascript; charset=utf-8");
			res.getWriter().print(callback+"("+result+")");
		}
		else{
			res.setContentType("text/plain");
			res.getWriter().print(result);
		}
	    res.getWriter().flush();
	}
	
	
	
}
